-module(hglobals).
-compile(export_all).

start() ->
    spawn(hglobals, loop, [dict:new()]).

%% loop( Dict ) ->
%%     receive
%% 	{put, ID, Key, Value} ->
%% 	    case dict:find(ID, Dict) of
%% 		{ok, ID_Content} ->
%% 		    NID_Content = case dict:find(Key, ID_Content) of
%% 			{ok, _} ->
%% 			    dict:append(Key, Value, dict:erase(Key, ID_Content));
%% 			error ->
%% 			    dict:append(Key, Value, ID_Content)
%% 		    end,
%% 		    loop( dict:append( ID, NID_Content, dict:erase(ID,Dict)) );
%% 		error ->
%% 		    loop( dict:append(ID, dict:append(Key, Value, dict:new()), dict:new()) ) %Create the new double dictionnary to store it all
%% 	    end;
%% 	{get, PID, ID, Key} ->
%% 	    case dict:find(ID, Dict) of
%% 		{ok, ID_Content} ->
%% 		    case dict:find(Key, ID_Content) of
%% 			{ok, Value} ->
%% 			    PID ! Value;
%% 			_ -> 
%% 			    PID ! not_found
%% 		    end,
%% 		    loop(Dict);
%% 		_ -> 
%% 		    PID ! not_found,
%% 		    loop( Dict )
%% 	    end
%%     end.
loop( Dict ) ->
    receive
	{put, ID, Key, Value} ->
	    case dict:find(ID, Dict) of
                error ->
                    %Create the new double dictionnary to store it all
		    loop( dict:append(ID, dict:append(Key, Value, dict:new()), Dict) ) ;
		{ok, [ID_Content|_]} ->
		    NID_Content = case dict:find(Key, ID_Content) of
			{ok, _} ->
			    dict:append(Key, Value, dict:erase(Key, ID_Content));
			error ->
			    dict:append(Key, Value, ID_Content)
		    end,
		    loop( dict:append( ID, NID_Content, dict:erase(ID,Dict)) )
	    end;
	{get, PID, ID, Key} ->
	    case dict:find(ID, Dict) of
		error -> PID ! not_found;
		{ok, [ID_Content|_]} ->
		    case dict:find(Key, ID_Content) of
                        error -> PID ! not_found;
			{ok, [Value|_]} -> PID ! Value
		    end
	    end,
            loop( Dict )
    end.

vput(ID, Key, Value) ->
    %io:format("Put : ~w << ~w~n", [Key, Value]),
    hglobals ! {put, ID, Key, Value},
    ok.

vget(ID, Key) ->
    hglobals ! {get, self(), ID, Key},
    Out = receive
	not_found ->
	    not_found;
	Value ->
	    Value
    end,
    %io:format("Got: ~w >> ~w~n", [Key, Out]),
    Out.
